/*
有一个二维矩阵 A 其中每个元素的值为 0 或 1 。
移动是指选择任一行或列，并转换该行或列中的每一个值：将所有 0 都更改为 1，将所有 1 都更改为 0。
在做出任意次数的移动后，将该矩阵的每一行都按照二进制数来解释，矩阵的得分就是这些数字的总和。
返回尽可能高的分数。

提示：
    1 <= A.length <= 20
    1 <= A[0].length <= 20
    A[i][j] 是 0 或 1

题解：
	有题知当最高位为1时值才可能是最大的
	其次，对每一列进行翻转（不包括最高位那列），使得每列1的个数不少于0的个数
	不需要对矩阵进行翻转操作，仅需要用变量记录值即可；对于列变换可以根据对应行是否变化来进行改变
 */
class Solution {
    public int matrixScore(int[][] A) {
        int n = A.length;
        int m = A[0].length;
        
        int ans = n * (1 << (m - 1));

        for (int i = 1; i < m; i ++) {  // 遍历每一列
            int cnt = 0;
            for (int j = 0; j < n; j ++) {  // 遍历每一行
                if (A[j][0] == 1) {  // 无需反转
                    cnt += A[j][i];
                } else {
                    cnt += (1 - A[j][i]);
                }
            }

            ans += Math.max(cnt, n - cnt) * (1 << (m - 1 - i));
        }

        return ans;
    }
}